package com.sky.sky_common.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 基于 JDK 11+ 的 HttpClient 封装工具类
 */
public class HttpClientUtil {

    private static final HttpClient client;
    private static final ObjectMapper objectMapper = new ObjectMapper();

    // 静态初始化 HttpClient
    static {
        client = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(10)) // 连接超时
                .followRedirects(HttpClient.Redirect.NORMAL) // 自动重定向
                .build();
    }

    /**
     * 发送 GET 请求
     *
     * @param url URL 地址
     * @return 响应体字符串
     * @throws Exception 网络或解析异常
     */
    public static String get(String url) throws Exception {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(30))
                .GET()
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        return handleResponse(response);
    }

    /**
     * 发送异步 GET 请求
     *
     * @param url URL 地址
     * @return CompletableFuture<String>
     */
    public static CompletableFuture<String> getAsync(String url) {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(30))
                .GET()
                .build();

        return client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(HttpClientUtil::handleResponse);
    }

    /**
     * 发送 POST 请求（JSON 数据）
     *
     * @param url  URL 地址
     * @param data 要发送的对象（将被序列化为 JSON）
     * @return 响应体字符串
     * @throws Exception 网络或序列化异常
     */
    public static String postJson(String url, Object data) throws Exception {
        String jsonBody = objectMapper.writeValueAsString(data);
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(30))
                .header("Content-Type", "application/json; charset=utf-8")
                .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        return handleResponse(response);
    }

    /**
     * 发送异步 POST JSON 请求
     */
    public static CompletableFuture<String> postJsonAsync(String url, Object data) {
        try {
            String jsonBody = objectMapper.writeValueAsString(data);
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(url))
                    .timeout(Duration.ofSeconds(30))
                    .header("Content-Type", "application/json; charset=utf-8")
                    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                    .build();

            return client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                    .thenApply(HttpClientUtil::handleResponse);
        } catch (JsonProcessingException e) {
            return CompletableFuture.failedFuture(e);
        }
    }

    /**
     * 发送 PUT 请求（JSON）
     */
    public static String putJson(String url, Object data) throws Exception {
        String jsonBody = objectMapper.writeValueAsString(data);
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(30))
                .header("Content-Type", "application/json; charset=utf-8")
                .PUT(HttpRequest.BodyPublishers.ofString(jsonBody))
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        return handleResponse(response);
    }

    /**
     * 发送 DELETE 请求
     */
    public static String delete(String url) throws Exception {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(30))
                .DELETE()
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        return handleResponse(response);
    }

    /**
     * 构建带查询参数的 URL
     *
     * @param baseUrl 基础 URL
     * @param params  查询参数 map
     * @return 完整 URL
     */
    public static String buildUrlWithParams(String baseUrl, Map<String, String> params) {
        if (params == null || params.isEmpty()) {
            return baseUrl;
        }

        StringBuilder sb = new StringBuilder(baseUrl);
        sb.append("?");
        for (Map.Entry<String, String> entry : params.entrySet()) {
            sb.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8))
              .append("=")
              .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8))
              .append("&");
        }
        // 移除最后一个 &
        if (sb.charAt(sb.length() - 1) == '&') {
            sb.setLength(sb.length() - 1);
        }
        return sb.toString();
    }

    /**
     * 处理响应，检查状态码
     */
    private static String handleResponse(HttpResponse<String> response) {
        int statusCode = response.statusCode();
        String body = response.body();

        if (statusCode >= 200 && statusCode < 300) {
            return body;
        } else {
            throw new RuntimeException("HTTP 请求失败，状态码: " + statusCode + ", 响应体: " + body);
        }
    }

    // 可选：添加带自定义 Header 的方法，或支持 form-data 等
}
